<?php

class Workset_Controller_Action_Helper_JQueryGrid extends Zend_Controller_Action_Helper_Abstract {

    private static $_conditions = array(
        'eq' => ' = ?',
        'ne' => ' != ?',
        'lt' => ' < ?',
        'le' => ' <= ?',
        'gt' => ' > ?',
        'ge' => ' >= ?',
        'bw' => ' like ?',
        'bn' => ' not like ?',
        'in' => ' in(?)',
        'ni' => ' not in(?)',
        'ew' => ' like ? ',
        'en' => ' not like ? ',
        'cn' => ' like ?  ',
        'nc' => ' not like ?  ',
    );

    protected $_columnFormatters = array();

    protected $_useColumnFormatter = false;

    function direct($source, $page = null, $total = null, $records = null, $cols = null, $analyle_cols = false) {
        $real_cols = array();
    	if ( $analyle_cols && is_array( $cols ) ) {
        	foreach ( $cols as $item ) {
        		$real_cols[] = $item['index'];
        	}
        	$cols = $real_cols;
        	unset( $real_cols );
        }
    	return $this->getRecords($source, $page, $total, $records, $cols);
    }

    function addColumnFormatter($colName, $formatter) {
        $this->_columnFormatters[$colName][] = $formatter;
        $this->_useColumnFormatter = true;
    }

    function formatColumn($colName, $value) {
        if (isset($this->_columnFormatters[$colName])) {

            $formatters = $this->_columnFormatters[$colName];

            foreach ($formatters as $formatter) {
                if ($formatter instanceof Zend_Filter_Interface) {
                    return $formatter->filter($value);

                } elseif ($formatter instanceof Closure) {
                    return  $formatter($value);
                    
                } else {
                    throw new Zend_Exception('Formatter must be an instance of Zend_Filter_Interface or Closure');
                }
            }

        }

        return $value;
    }

    function getRecords($source, $page, $total, $records, $cols = null) {
        $records = array(
            'rows' => array(),
            'page' => $page,
            'total' => $total,
            'records' => $records
        );

        foreach ($source as $item) {
            if ($item instanceof Workset_Model_Object_Abstract) {
                $item = $item->toArray();
            }

            if (is_array($item)) {

                if ($this->_useColumnFormatter) {
                    foreach (array_keys($this->_columnFormatters) as $colName) {
                        $item[$colName] = $this->formatColumn($colName, $item[$colName]);
                    }
                }

                if (is_array($cols) && $cols) {
                   $fields = array_flip($cols);
                   $row = array_intersect_key($item, $fields);
                   $records['rows'][] = array(
                       'id' => (int)$item['id'],
                       'cell' => array_values(array_merge($fields, $row))
                   );
                } else {
                   $records['rows'][] =array(
                       'id' => (int)$item['id'],
                       'cell' => array_values($item)
                   ) ;
                }
            }
        }
        
        return $records;
    }

    function getFields($jsonData) {
        if (!is_array($jsonData)) {
			$jsonData = Zend_Json::decode($jsonData);
		}

        $result = array();

        if (empty($jsonData['rules'])) {
            return $result;
        }

        foreach ((array)$jsonData['rules'] as $key => $rule) {
            $result[$rule['field']][] = $key;
        }

        return $result;
    }

    function getConditions($jsonData) {
        if (!is_array($jsonData)) {
			$jsonData = Zend_Json::decode($jsonData);
		}

        $result = array();

        if (empty($jsonData['rules'])) {
            return $result;
        }

        foreach ((array)$jsonData['rules'] as $key => $rule) {
            if (!empty(self::$_conditions[$rule['op']])) {
                $result[$rule['field']][] = self::$_conditions[$rule['op']];
            }
        }

        return $result;
    }

    function getFilter($jsonData, $model = null) {
        $result = array();

        if (!$jsonData) {
            return $result;
        }

		if (is_array($jsonData)) {
			return $jsonData;
		}

        $fields = null;

        $multiData = array();

        if (is_array($model)) {
            foreach ($model as $spec) {
                if (!isset($spec['search']) || $spec['search'] == true) {
                    $fields[] = $spec['name'];
                }
            }
        }
        
        $filter = Zend_Json::decode($jsonData);

        if (!empty($filter['rules'])) {

            if ($filter['groupOp'] == 'OR') {
                $result['GROUP'] = 'OR';
				$result[0] = array();
				$point = & $result[0];
            } else {
				$point = & $result;
			}

            foreach ((array)$filter['rules'] as $key => $rule) {

				if (null !== $fields && !in_array($rule['field'], $fields)) {
					continue;
				}

				if (!isset(self::$_conditions[$rule['op']])) {
                    continue;
                }

				$k = $rule['field'] . self::$_conditions[$rule['op']];

				//множество IN
                if ($rule['op'] == 'in' || $rule['op'] == 'ni') {

                    $rule['data'] = explode(',', $rule['data']);
                    $rule['data'] = array_map('trim', $rule['data']);

					if (isset($point[$k])) {
						$point[$k] = array_merge($point[$k], $rule['data']);
						continue;
					}
                } elseif ($rule['op'] == 'eq' || $rule['op'] == 'ne') {

                    if (isset($point[$k])) {
                        $multiData[$k] = $rule['field'].($rule['op'] == 'eq' ? self::$_conditions['in'] : self::$_conditions['ni']);
                        $point[$k] = (array)$point[$k];
                        $point[$k][] = $rule['data'];
                        continue;
                    } 

                } elseif ($rule['op'] == 'bw' || $rule['op'] == 'bn') {
					$rule['data'] = ltrim($rule['data'], '%');
					$rule['data'] .= '%';

				} elseif ($rule['op'] == 'ew' || $rule['op'] == 'en') {
					$rule['data'] = rtrim($rule['data'], '%');
					$rule['data'] = '%'.$rule['data'];

				} elseif ($rule['op'] == 'cn' || $rule['op'] == 'nc') {
					$rule['data'] = trim($rule['data'], '%');
					$rule['data'] = '%'.$rule['data'].'%';

				} 

				$point[$k] = $rule['data'];

            }

            if (empty($point)) {
                return array();
            }

            if ($multiData) {
                foreach ($multiData as $k => $op) {
                    $point[$op] = $point[$k];
                    unset($point[$k]);
                }
            }

        }

        return $result;
    }

}
